package com.bestcem.xm.survey.export.type;

import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.survey.export.BaseTypeHandler;
import com.bestcem.xm.survey.grpc.client.dto.QstructsDto;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

import static com.bestcem.xm.survey.enums.QuestionTypeEnum.QUESTION_TYPE_CASCADE;

/**
 * 级联题
 */
@Component
public class CascaderHandler implements BaseTypeHandler {

    @Override
    public Map<String, String> getSelectColumnChangeDictV2(JSONObject data, String dtype) {
        Map<String, String> column_change_dict = new HashMap();
        Integer levelNum = levelNum(data);
        List<String> group_list = (List<String>) data.getOrDefault("group_list", Collections.emptyList());
        levelNum = Math.min(group_list.size(), levelNum);
        for (int i = 0; i < levelNum; i++) {
            String group = group_list.get(i);
            column_change_dict.put(getSelectRealcolV2(data, i + 1), getSelectReadablecolV2(group, data, i + 1));
        }
        return column_change_dict;
    }

    private String getSelectReadablecolV2(String group, JSONObject data, int index) {
        return String.format("%s__第%s级__%s", BaseTypeHandler.clearHtml(data.getString("title")), index, BaseTypeHandler.clearHtml(group));
    }

    private String getSelectRealcolV2(JSONObject data, int index) {
        return String.format("%s__%s", data.getString("cid"), index);
    }

    public Integer levelNum(JSONObject data) {
        List<JSONObject> items = ((List<JSONObject>) data.getOrDefault("option_list", Collections.emptyList()));
        Collections.sort(items, (a, b) -> {
            String a1 = a.getString("otype");
            String b1 = b.getString("otype");
            return a1.charAt(a1.length() - 1) - b1.charAt(b1.length() - 1);
        });
        Integer level_num;
        try {
            String[] value = ((String) items.get(items.size() - 1).getOrDefault("otype", "")).split("_");
            level_num = Integer.valueOf(value[value.length - 1]);
        } catch (Exception e) {
            level_num = 2;
        }
        return level_num;
    }

    @Override
    public List<String> getSelectColumnListV2(JSONObject data, String dtype) {
        List<String> column_list = new ArrayList();
        Integer levelNum = levelNum(data);
        List<String> group_list = (List<String>) data.getOrDefault("group_list", Collections.emptyList());
        levelNum = Math.min(group_list.size(), levelNum);
        for (int i = 0; i < levelNum; i++) {
            //String group = group_list.get(i);
            column_list.add(getSelectRealcolV2(data, i + 1));
        }
        return column_list;
    }

    @Override
    public Map<Object, Object> getSelectAnswerDictV2(JSONObject dataValue, Object answers, String dtype, Boolean score_apply_type) {
        Map<Object, Object> data = new HashMap<>();
        Integer levelNum = levelNum(dataValue);
        List<String> group_list = (List<String>) dataValue.getOrDefault("group_list", Collections.emptyList());
        levelNum = Math.min(group_list.size(), levelNum);
        if (Objects.isNull(answers)) {
            for (int i = 0; i < levelNum; i++) {
                //np.nan 可以理解为null
                data.put(getSelectRealcolV2(dataValue, i + 1), null);
            }
        } else {
            Map<String, List<Integer>> answersValue = (Map<String, List<Integer>>) answers;
            answersValue.forEach((i, answer) -> {
                Integer index = Integer.valueOf(i);
                Integer firstAnswer;
                if (Objects.nonNull(answer) && Objects.nonNull(firstAnswer = answer.get(0))) {
                    List<JSONObject> option_list = (List<JSONObject>) dataValue.getOrDefault("option_list", Collections.emptyList());
                    if ("readable".equals(dtype)) {
                        Map<Integer, String> option_dict = new HashMap<>();
                        option_list.forEach(v -> option_dict.put(v.getInteger("seq"), v.getString("title")));
                        data.put(getSelectRealcolV2(dataValue, index), BaseTypeHandler.clearHtml(option_dict.getOrDefault(firstAnswer, "")));
                    } else {
                        Map<Integer, String> gid_oid_dict = new HashMap<>();
                        option_list.forEach(v -> gid_oid_dict.put(v.getInteger("gid"), v.getString("oid")));
                        //np.nan 可以理解为null
                        data.put(getSelectRealcolV2(dataValue, index), gid_oid_dict.get(firstAnswer));
                    }
                } else {
                    data.put(getSelectRealcolV2(dataValue, index), null);
                }
            });
        }
        return data;
    }

    @Override
    public List<List<String>> getVarLabelsV2(JSONObject dataValue, boolean not01, boolean need_title) {
        List<List<String>> data = new ArrayList<>();
        List<JSONObject> old_option_list = (List<JSONObject>) dataValue.get("option_list");
        List<JSONObject> option_list = old_option_list.stream().sorted(Comparator.comparing(a -> a.getString("ooid"))).collect(Collectors.toList());
        String[] otypeArray = ((String) option_list.get(option_list.size() - 1).get("otype")).split("_");
        int level_count = Integer.parseInt(otypeArray[otypeArray.length - 1]);
        List<Integer> level_list = new ArrayList<>();
        for (int i = 0; i < level_count; i++) {
            level_list.add(i + 1);
        }
        List<JSONObject> level_first = old_option_list.stream().filter(v -> {
            String[] array = ((String) v.get("otype")).split("_");
            return "1".equals(array[array.length - 1]);
        }).collect(Collectors.toList());

        List<JSONObject> level_second = old_option_list.stream().filter(v -> {
            String[] array = ((String) v.get("otype")).split("_");
            return "2".equals(array[array.length - 1]);
        }).collect(Collectors.toList());

        List<JSONObject> level_third = old_option_list.stream().filter(v -> {
            String[] array = ((String) v.get("otype")).split("_");
            return "3".equals(array[array.length - 1]);
        }).collect(Collectors.toList());

        List<JSONObject> level_fourth = old_option_list.stream().filter(v -> {
            String[] array = ((String) v.get("otype")).split("_");
            return "4".equals(array[array.length - 1]);
        }).collect(Collectors.toList());
        String cid = dataValue.getString("cid");
        String title = getUnquotedStr(dataValue.getString("title"), true);
        //对层级进行处理
        List<String> var_list = new ArrayList(), val_list = new ArrayList();
        level_list.forEach(index -> {
            var_list.add(String.format("VARIABLE LABELS %s__l%s '%s:第%s级'."
                    , cid, index, title, index));
            if ("1".equals(index)) {
                formatItemValue(cid, val_list, index, level_first, level_count, title);
            } else if ("2".equals(index)) {
                formatItemValue(cid, val_list, index, level_second, level_count, title);
            } else if ("3".equals(index)) {
                formatItemValue(cid, val_list, index, level_third, level_count, title);
            } else if ("4".equals(index)) {
                formatItemValue(cid, val_list, index, level_fourth, level_count, title);
            }
        });
        data.add(var_list);
        data.add(val_list);
        return data;
    }

    private void formatItemValue(String cid, List val_list, Integer index, List<JSONObject> level_list, Integer level_count, String title) {
        val_list.add(String.format("ADD VALUE LABELS %s__l%s", cid, index));
        int size = level_list.size();
        for (int i = 0; i < size; i++) {
            JSONObject item = level_list.get(i);
            val_list.add(String.format("    %s '%s'%s", i, title, size == i + 1 ? "" : "."));
        }
    }

    @Override
    public List<String> getSpssCodeV2(JSONObject param, QstructsDto qstruct) {
        List<String> head_list = new ArrayList();
        Integer level_num = levelNum(param);
        for (int idx = 0; idx < level_num + 1; idx++) {
            head_list.add(String.format("%s__l%s", param.getString("cid"), idx));
        }
        return head_list;
    }

    @Override
    public String getQuestionTypeValue() {
        return QUESTION_TYPE_CASCADE.getValue();
    }
}
